/**
 * Copyright (C) 2013 Denatics Development
 * 
 * Programmed by David Tiersch <dtiersch@denatics.com>
 * 
 * This file is part of B0mberman.
 * 
 * B0mberman is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * B0mberman is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with B0mberman. If not, see <http://www.gnu.org/licenses/>.
 */
package com.denatics.bomberman.gui;

import com.denatics.bomberman.Config;
import com.denatics.bomberman.entities.Entity;
import com.denatics.bomberman.sprites.Sprite;

/**
 * This Object is responsible to create any Images.
 * 
 * @author David Tiersch <dtiersch@denatics.com>
 */
public class Bitmap {

    /**
     * Array with the image of the Gamefield being rendered.
     */
    private int[] pixels;

    /**
     * Width of the Image.
     */
    private final int width;

    /**
     * Height of the Image.
     */
    private final int height;

    /**
     * Creates the Basic of the Image.
     * 
     * @param imageWidth
     *            Width of the Image
     * @param imageHeight
     *            Height of the Image
     */
    public Bitmap(final int imageWidth, final int imageHeight) {
        this.width = imageWidth;
        this.height = imageHeight;
        this.pixels = new int[this.width * this.height];
    }

    /**
     * Returns an Array of integers which contains the single pixel-values.
     * 
     * @return array of pixels
     */
    public final int[] getPixels() {
        return this.pixels;
    }

    /**
     * Paints an image into this Bitmap.
     * 
     * @param source
     *            the source from where the part of the image comes from
     * @param offX
     *            X-Offset where to begin the inserting of the Image
     * @param offY
     *            Y-Offset where to begin the inserting of the Image
     * @param srcOffX
     *            X-Offset in the source-File, where the Image begins
     * @param srcOffY
     *            Y-Offset in the source-File, where the Image begins
     * @param srcWidth
     *            Width of the Image in the source-File
     * @param srcHeight
     *            Height of the Image in the source-File
     */
    private void draw(final Bitmap source, final int offX, final int offY,
            final int srcOffX, final int srcOffY, final int srcWidth,
            final int srcHeight) {
        for (int y = 0; y < srcHeight * Config.SCALE; y++) {
            final int bitYCur = offY + y;
            if (bitYCur < 0 || bitYCur >= this.height) {
                continue;
            }

            for (int x = 0; x < srcWidth * Config.SCALE; x++) {
                final int bitXCur = offX + x;
                if (bitXCur < 0 || bitXCur >= this.width) {
                    continue;
                }

                final int src =
                        source.pixels[(srcOffX + x / Config.SCALE)
                                + (srcOffY + y / Config.SCALE) * source.width];
                if (src >= 0) {
                    this.pixels[bitXCur + bitYCur * this.width] = src;
                }
            }
        }
    }

    /**
     * Paints an entity into this Bitmap.
     * 
     * @param entity
     *            the Entity which is going to get painted
     * @param offX
     *            X-Offset of tiles where to begin the inserting of the Image
     * @param offY
     *            Y-Offset of tiles where to begin the inserting of the Image
     */
    protected final void draw(final Entity entity, final int offX,
            final int offY) {
        this.draw(Images.TEXTURE, offX * Config.ENTITYSIZE * Config.SCALE, offY
                * Config.ENTITYSIZE * Config.SCALE, entity.getTexPosition()[0]
                * Config.ENTITYSIZE, entity.getTexPosition()[1]
                * Config.ENTITYSIZE, Config.ENTITYSIZE, Config.ENTITYSIZE);
    }

    /**
     * Paints a Sprite into this Bitmap.
     * 
     * @param sprite
     *            the Entity which is going to get painted
     * @param offX
     *            X-Offset of tiles where to begin the inserting of the Image
     * @param offY
     *            Y-Offset of tiles where to begin the inserting of the Image
     */
    protected final void draw(final Sprite sprite, final int offX,
            final int offY) {
        this.draw(Images.SPRITES, (int) ((offX + (float) sprite.getOffset()[0]
                / (float) Config.MOVEMENT_SPEED)
                * Config.ENTITYSIZE * Config.SCALE),
                (int) ((offY + (float) sprite.getOffset()[1]
                        / (float) Config.MOVEMENT_SPEED)
                        * Config.ENTITYSIZE * Config.SCALE),
                sprite.getTexPosition()[0] * Config.SPRITESIZE,
                sprite.getTexPosition()[1] * Config.SPRITESIZE,
                Config.SPRITESIZE, Config.SPRITESIZE);
    }
}
